package gudaziEx.util;

import ComPuter.entity.ComputerChain;
import com.alibaba.fastjson.JSONObject;
import commons.entity.Constant;
import commons.entity.CpMissonResults;
import commons.entity.NativeCp;
import commons.entity.TrainResults;
import commons.util.GameUtil;
import commons.util.ProcessDealUtil;
import fgoScript.entity.PointColor;
import gudaziEx.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.awt.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ChainUtil {
    private static final Logger LOGGER = LogManager.getLogger(ChainUtil.class);

    public static List<ClickUnit> getClickUnits(String directoryName,boolean  ifSort) throws Exception {
        String path = NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/" +directoryName;
        List<ClickUnit> cuList = new ArrayList<>();
        File file = new File(path);
        String filepath;
        if (file.isDirectory()){
            File[] files = file.listFiles();
            int fileSize = files.length;
            File tempFile;
            for (int i = 0; i < fileSize; i++) {
                tempFile = files[i];
                if (tempFile.isFile()){
                    cuList.addAll(JSONObject.parseArray(GameUtil.getJsonString(tempFile.getAbsolutePath()), ClickUnit.class));
                }
            }
            checkSubCulist(cuList,directoryName);
            if (ifSort){
                sortCulist(cuList);
            }
            // 排序
        }else{
            throw new Exception("this is not a json directory name path!");
        }
        return cuList;
    }
    public static List<ClickUnit> getClickUnitsFromSubFilePath(String parentPath, String subFileName, String  subCheckRootPath) throws Exception {
        //  "../COMMONS/LO_CLICK_SUB"
        String subCheckRootPathStr = StringUtils.isBlank(subCheckRootPath) ? "" : subCheckRootPath+ "/";
        String path = NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/" +parentPath + "/" + subCheckRootPathStr + subFileName;
        File file = new File(path);
        List<ClickUnit> cuList = null;
        if (file.isFile()){
            cuList = JSONObject.parseArray(GameUtil.getJsonString(file.getAbsolutePath()), ClickUnit.class);
        }
        if (cuList == null){
            subCheckRootPath = subCheckRootPath.replace("../","../../");
            cuList = getClickUnitsFromSubFilePath(parentPath,subFileName,subCheckRootPath);
        }
        return cuList;
    }
    private static void sortCulist(List<ClickUnit> cuList){
        int size = cuList.size();
        ClickUnit tempCu;
        for (int i = 0; i < size; i++) {
            tempCu = cuList.get(i);
            Collections.sort(tempCu.getCheckList(), new Comparator<PointColor>() {
                @Override
                public int compare(PointColor o1, PointColor o2) {
                   int flag = 0;
                   if (o1.isEqual()){
                       flag = -1;
                   }else if(!o1.isEqual() && !o2.isEqual()){
                       flag = 0;
                   }else if(!o1.isEqual() && o2.isEqual()){
                       flag = 1;
                   }
                    return flag;
                }
            });
        }
    }
    private static void checkSubCulist(List<ClickUnit> cuList, String parentPath) throws Exception {
        int size = cuList.size();
        ClickUnit tempCu;
        ClickUnit subCu;
        List<String> subCheckPathList;
        String subCheckRootPath;
        List<ClickUnit> subCuList;
        String subFileName;
        int subFileNameListSize;
        int subCuListSize;
        for (int i = 0; i < size; i++) {
            tempCu = cuList.get(i);
            subCheckPathList = tempCu.getSubCheckPathList();
            subCheckRootPath = tempCu.getSubCheckRootPath();
            if (subCheckPathList != null){
                subFileNameListSize = subCheckPathList.size();
                for (int j = 0; j < subFileNameListSize; j++) {
                    subFileName = subCheckPathList.get(j);
                    subCuList = ChainUtil.getClickUnitsFromSubFilePath(parentPath, subFileName, subCheckRootPath);
                    subCuListSize = subCuList.size();
                    for (int k = 0; k < subCuListSize; k++) {
                        subCu = subCuList.get(k);
                        tempCu.getCheckList().addAll(subCu.getCheckList());
                    }
                }
            }
        }
    }
    public static ClickChain getClickChain(String directoryName){
        String filepath = NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/" +directoryName  + "/ClickChain/ClickChain.json";
        ClickChain cc = JSONObject.parseObject(GameUtil.getJsonString(filepath), ClickChain.class);
        return cc;
    }
    public static RunningChain getRunningChain(){
        String filepath = NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/RunningChain_"+NativeCp.getUserName()+".json";
        RunningChain rc = JSONObject.parseObject(GameUtil.getJsonString(filepath), RunningChain.class);
        return rc;
    }
    public static ComputerChain getComPuterChain(){
        String filepath = NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/ComputerChain_"+NativeCp.getUserName()+".json";
        ComputerChain cc = JSONObject.parseObject(GameUtil.getJsonString(filepath), ComputerChain.class);
        return cc;
    }
    public static String getShiftIningPathReflash(){
        RunningChain rc = getRunningChain();
        return rc.getShiftIningPath();
    }
    /** 设置检测json **/
    public static void saveRunningChain(RunningChain rc){
        String text = JSONObject.toJSONString(rc);
        ChainUtil.saveFile(text,NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/RunningChain_"+ NativeCp.getUserName() + ".json");
    }
    /** 设置检测json **/
    public static void saveMoveThings(MoveThings moveThings,String fileName){
        String text = JSONObject.toJSONString(moveThings);
        String filepath = System.getProperty("user.dir") + "/config/" + Constant.MOVE+ "/" ;
        try {
            ChainUtil.createPathAndSaveFile(text,filepath,fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /** 设置检测json **/
    public static void saveTrainResults(TrainResults trainResults){
        String text = JSONObject.toJSONString(trainResults);
        String filepath = System.getProperty("user.dir") + "/config/" + Constant.FGO+ "/" ;
        try {
            ChainUtil.createPathAndSaveFileOverWrite(text,filepath,"TrainResults.json");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /** 设置检测json **/
    public static void saveCpMissonResults(CpMissonResults cpMissonResults){
        String text = JSONObject.toJSONString(cpMissonResults);
        String filepath = System.getProperty("user.dir") + "/config/" + Constant.FGO+ "/" ;
        try {
            ChainUtil.createPathAndSaveFileOverWrite(text,filepath,"CpMissonResults.json");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void saveMovePoints(MovePoints movePoints,String fileName){
        String text = JSONObject.toJSONString(movePoints);
        String filepath = System.getProperty("user.dir") + "/config/" + Constant.MOVE_POINTS+ "/" ;
        try {
            ChainUtil.saveFile(text,NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/ComputerChain_"+ NativeCp.getUserName() + ".json");

            ChainUtil.createPathAndSaveFile(text,filepath,fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /** 设置检测json **/
    public static void saveMovePoints(MovePoints mp){
        String filepath = System.getProperty("user.dir") + "/config/" + Constant.MOVE_POINTS+ "/" ;
        String text = JSONObject.toJSONString(mp);
        File directory = new File(filepath);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建目录
        }
        String decodedFileName = "";
        try {
             decodedFileName = new String( mp.getName().getBytes(StandardCharsets.UTF_8), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 创建新文件
        File file = new File(directory, decodedFileName);
        saveFile(text,file.getAbsolutePath());

    }
    public static MoveThings getMoveThingsChain(String filename){
        String filepath = System.getProperty("user.dir") + "/config/" + Constant.MOVE+ "/"+filename;
        MoveThings mt = JSONObject.parseObject(GameUtil.getJsonString(filepath), MoveThings.class);
        return mt;
    }
    /** 设置检测json **/
    public static void saveComputerChain(ComputerChain cc){
        String text = JSONObject.toJSONString(cc);
        ChainUtil.saveFile(text,NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX + "/ComputerChain_"+ NativeCp.getUserName() + ".json");
    }
    public static void createPathAndSaveFile(String content, String path, String fileName) throws IOException {
        File directory = new File(path);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建目录
        }
        // 创建新文件
        File file = new File(directory, fileName.trim());
        if (file.exists()) {
            ProcessDealUtil.displayTray("文件名重复","请重新命名！", TrayIcon.MessageType.WARNING);
            throw new IOException("File already exists: " + file.getAbsolutePath());
        }
        saveFile(content,file.getAbsolutePath());
    }
    public static void createPathAndSaveFileOverWrite(String content, String path, String fileName) throws IOException {
        File directory = new File(path);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建目录
        }
        // 创建新文件
        File file = new File(directory, fileName.trim());
        saveFile(content,file.getAbsolutePath());
    }
    public static void saveFiless(String content, String path) {

        FileWriter fwriter = null;
        try {
            fwriter = new FileWriter(path,false);
            fwriter.write(content);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                fwriter.flush();
                fwriter.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    public static void saveFile(String content, String path){

        try {
            FileOutputStream fos = new FileOutputStream(path);
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
            Writer writer = new BufferedWriter(osw);
            writer.write(content);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void deleteTempFile(){
        String filepath = NativeCp.getUserDir() + "/config/"+ Constant.CLICK_EX   + "/temp";
        File file = new File(filepath);
        List<ClickUnit> cuList = new ArrayList<>();
        if (file.isDirectory()){
            File[] files = file.listFiles();
            int fileSize = files.length;
            File tempFile;
            for (int i = 0; i < fileSize; i++) {
                tempFile = files[i];
                if (tempFile.isFile()){
                    tempFile.delete();
                }
            }
        }else{
            LOGGER.error("this is not a json directory name path!");
        }
    }

    public static void main(String[] args) {
        ChainUtil.saveComputerChain(new ComputerChain());
    }
}
